import re

from django.contrib.auth import authenticate
from django.contrib.auth.models import User

from django.core.serializers import get_serializer

from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from config.dbs.redisConfig import KEY_TEMPLATE
from users.models import UserDetail, Area, Address


class UserSerializer(ModelSerializer):
    # 新增验证码字段
    verify = serializers.CharField(write_only=True)
    uuid = serializers.CharField(write_only=True)
    sex = serializers.IntegerField(read_only=True,source="userdetail.sex")
    birthday = serializers.DateTimeField(read_only=True,source="userdetail.birthday")
    phone = serializers.CharField(read_only=True,source="userdetail.phone")
    avatar = serializers.CharField(read_only=True, source="userdetail.avatar")
    # 新增uuid字段
    class Meta:
        model = User
        # 展示字段
        #fields = "__all__"
        exclude = ["first_name","last_name",
                   "date_joined","groups",
                   "user_permissions","last_login"
                  ]

        extra_kwargs = {
            "password": {"write_only": True},
            "is_superuser": {"read_only": True},
            "is_active": {"read_only": True},
            "is_staff": {"read_only": True},
        }
    def validate(self, attrs):
        # 获取前端传入的数据
        uuid = attrs.get('uuid')
        # 获取前端传入的验证码
        verify = attrs.get('verify')
        # 获取redis缓存对象
        cache = get_redis_connection(alias="verify_codes")
        # 根据redis的可以查询值
        redis_verify = cache.get(KEY_TEMPLATE %('register', uuid))
        # 获取完前端的验证码就要进行redis销毁
        cache.delete(KEY_TEMPLATE %('register', uuid))
        # 验证
        if not redis_verify:
            raise serializers.ValidationError("验证码过期")

        if redis_verify.upper() != verify.upper():
            raise serializers.ValidationError("验证码错误")
        return attrs

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    # 新增uuid
    uuid = serializers.CharField(write_only=True)
    # 新增验证码
    verify = serializers.CharField(write_only=True)

    def validate(self, attrs):
        uuid = attrs.get('uuid')
        verify = attrs.get('verify')
        username = attrs.get('username')
        password = attrs.get('password')

        # 获取redis缓存对象
        cache = get_redis_connection(alias="verify_codes")
        # 获取验证码
        redis_verify = cache.get(KEY_TEMPLATE %('login', uuid))
        # 删除缓存对象
        cache.delete(KEY_TEMPLATE %('login', uuid))
        # 判断是否存在验证
        if not redis_verify:
            raise serializers.ValidationError("验证码过期")
        if redis_verify.upper() != verify.upper():
            raise serializers.ValidationError("验证码错误")

        # 用户身份校验
        user = authenticate(username=username, password=password)
        if not user:
            raise serializers.ValidationError("账号密码不正确")

        # 身份认证成功 制作token令牌
        refresh = self.get_token(user)

        # 把token令牌信息 返回客户端
        return {'user': user.username, 'token': str(refresh.access_token)}


# 用户详情序列化器
class UserDetailSerializer(ModelSerializer):
    class Meta:
        model = UserDetail
        exclude = ["is_delete"]



# 用户密码修改序列化器
class UpdatePasswordSerializer(serializers.Serializer):
    password = serializers.CharField(max_length=60,label="原密码",help_text="原密码")
    new_password = serializers.CharField(max_length=60,label="新密码",help_text="新密码")
    re_new_password = serializers.CharField(max_length=60,label="确认新密码",help_text="确认新密码")

    def validate(self,attrs):
        if attrs["new_password"] != attrs["re_new_password"]:
            raise serializers.ValidationError("两次密码不一致")


        if attrs["new_password"] == attrs["password"]:
            raise serializers.ValidationError("新密码不能和原密码一样")
        # 获取当前的登录用户信息
        user = self.context["request"].user
        # 判断用户密码是否正确
        if not user.check_password(attrs["password"]):
            raise serializers.ValidationError("原密码错误")

        return attrs


class AreaSerializer(ModelSerializer):
    class Meta:
        model = Area
        fields = ["id","name"]


class ParentSerializer(ModelSerializer):
    area_set = AreaSerializer(many=True, read_only=True)
    class Meta:
        model = Area
        fields = ["id","name","area_set"]

class AddressSerializer(ModelSerializer):
    province_name = serializers.CharField(source="province.name", read_only=True)
    city_name = serializers.CharField(source="city.name", read_only=True)
    district_name = serializers.CharField(source="district.name", read_only=True)
    class Meta:
        model = Address
        exclude = ["is_delete"]

    def validate_mobile(self,value):
        if not re.match(r"1[3-9]\d{9}$",value):
            raise serializers.ValidationError("手机格式错误")
        return value


